package cn.itsource.system.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.itsource.base.util.*;
import cn.itsource.global.exception.BusinessException;
import cn.itsource.system.domain.dto.PhoneUserFormDto;
import cn.itsource.system.service.IVerifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyServiceImpl implements IVerifyService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private SmsUtils smsUtils;


    //图片验证码 保存到redis里面去 设置过期时间5分钟
    //最后返回图片 字符串的图片
    @Override
    public AjaxResult getImgVerifyCode(String key) {
        //code要去生成一个图片验证码
//        String code = StrUtils.getComplexRandomString(4);
        //糊涂工具包的
        //做了两个事情 1帮我自动生产验证码 2帮我生产base64的字符串图片
        CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(115, 42, 4, 5);
        String imageBase64 = circleCaptcha.getImageBase64();//字符串图片
        //根据key去绑定一个code  随机生产
        redisTemplate.opsForValue().set(key,circleCaptcha.getCode(),5, TimeUnit.MINUTES);
        return AjaxResult.me().setResultObj(imageBase64);
    }

    // 1.null的异常问题   redis里面没有
    // 2.区分大小写校验 不好
    @Override
    public AjaxResult sendMobileCode(PhoneUserFormDto phoneUserFormDto) {
        String key = phoneUserFormDto.getKey();
        boolean bl =  redisTemplate.hasKey(key);//返回的是boolean 有true 没有 false
        if(!bl){
            return AjaxResult.me().setMessage("图片验证码已过期!").setSuccess(false);
        }
        //比较值对不对
        Object o = redisTemplate.opsForValue().get(key);
        if(!phoneUserFormDto.getImageCode().equalsIgnoreCase(o.toString())){
            return AjaxResult.me().setMessage("图片验证码不一致!").setSuccess(false);
        }
        sendSms(phoneUserFormDto);

        return AjaxResult.me();
    }

    /**
     * 发送短信的逻辑
     * 额外需求
     *    2分钟之内  发同样
     *    3分钟之间  发不一样
     * 额外需求
     *    一个用户1天只能发送10条
     * @param phoneUserFormDto
     */
    private void sendSms(PhoneUserFormDto phoneUserFormDto) {
        String smsCode = StrUtils.getRandomString(6);
        String phone = phoneUserFormDto.getPhone();
        String smsCodeKey = BusinessKey.BK_REGISTER+BusinessKey.BK_SPLIT + phone;
        String MaliceKey = BusinessKey.BK_MALICE+BusinessKey.BK_SPLIT + phone;
        //-----------------------------------------------------------
        if(redisTemplate.hasKey(MaliceKey)){//有才加
            redisTemplate.opsForValue().increment(MaliceKey);
            if((Integer)redisTemplate.opsForValue().get(MaliceKey) > 10){
                throw new BusinessException(ErrorCode.RUNTIME_SYSTEM_MALICE_ERROR.getCode());
            }
        }else {
            redisTemplate.opsForValue().set(MaliceKey,1,24,TimeUnit.HOURS);
        }

        //---------------------------

        //我在发送手机验证码时  应该去验证一下是否已经发送过
        if (redisTemplate.hasKey(smsCodeKey)) {//如果redis里面没有 就是第一次
            Long expire = redisTemplate.getExpire(smsCodeKey);//返回的剩余过期时间
            if(expire>60){//在两分钟之内
                //一定是上一次的code
                Object o = redisTemplate.opsForValue().get(smsCodeKey);
                smsCode = o.toString();
            }
        }
        //发送短信
        System.out.println(smsCode);
//        smsUtils.sendMsg(phoneUserFormDto.getPhone(),smsCode);//自动发送短信
        //存放redis
        redisTemplate.opsForValue().set(smsCodeKey,smsCode,3,TimeUnit.MINUTES);//180s
    }
}
